package com.xinqi.modules.exam.student.controller.web;

import com.xinqi.common.base.data.IdsDTO;
import com.xinqi.common.base.error.CommonErrors;
import com.xinqi.common.base.response.PageInfo;
import com.xinqi.common.base.response.R;
import com.xinqi.modules.exam.common.manager.CommonClassManager;
import com.xinqi.modules.exam.paper.domain.CourseExamPaperEntity;
import com.xinqi.modules.exam.student.dto.req.CourseExamPaperStudentManualDTO;
import com.xinqi.modules.exam.student.dto.req.CourseExamPaperStudentMarkDTO;
import com.xinqi.modules.exam.student.dto.req.CourseExamPaperStudentQueryDTO;
import com.xinqi.modules.exam.student.dto.req.CourseExamPaperStudentRejectDTO;
import com.xinqi.modules.exam.student.dto.req.CourseExamPaperStudentRemindDTO;
import com.xinqi.modules.exam.student.dto.req.CourseExamPaperStudentStartDTO;
import com.xinqi.modules.exam.student.dto.req.CourseExamPaperStudentSubmitDTO;
import com.xinqi.modules.exam.student.dto.req.CourseExamPaperStudentUpdateDTO;
import com.xinqi.modules.exam.student.dto.rsp.CourseExamPaperExtractResultDTO;
import com.xinqi.modules.exam.student.dto.rsp.CourseExamPaperStudentDetailDTO;
import com.xinqi.modules.exam.student.dto.rsp.CourseExamPaperStudentListDTO;
import com.xinqi.modules.exam.student.service.CourseExamPaperStudentService;
import com.xinqi.modules.exam.utils.StudentHelp;
import com.xinqi.modules.user.user.dto.rsp.UserBaseInfoDO;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.RequiredArgsConstructor;
import org.apache.commons.lang3.ArrayUtils;
import org.springdoc.api.annotations.ParameterObject;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.Stream;

/**
 * 课程测评学生答题WEB控制层
 *
 * @author: linkai
 * @date: 2023/07/02
 */
@Tag(name = "Web-课程测评学生答题", description = "课程测评学生答题Web接口")
@RestController
@RequestMapping("/web/exam-paper")
@RequiredArgsConstructor
public class CourseExamPaperStudentWebController {
    private final CourseExamPaperStudentService courseExamPaperStudentService;
    private final CommonClassManager commonClassManager;
    private final StudentHelp studentHelp;

    /**
     * 课程测评试卷-列表-老师端
     */
    @Operation(summary = "课程测评学生-列表-老师端")
    @GetMapping("/{exam-id}/student/list")
    public R<List<CourseExamPaperStudentListDTO>> list(
        @Parameter(description = "测评ID", example = "100001") @PathVariable("exam-id") Long examId,
        @ParameterObject CourseExamPaperStudentQueryDTO dto
    ) {
        dto.setExamId(examId);
        List<CourseExamPaperStudentListDTO> list = courseExamPaperStudentService.findStudentList(dto);
        return R.data(list);
    }

    /**
     * 课程测评学生-分页-老师端
     */
    @Operation(summary = "课程测评学生-分页-老师端")
    @GetMapping("/{exam-id}/student/page")
    public R<PageInfo<CourseExamPaperStudentListDTO>> page(
        @Parameter(description = "测评ID", example = "100001") @PathVariable("exam-id") Long examId,
        @ParameterObject CourseExamPaperStudentQueryDTO dto
    ) {
        dto.setExamId(examId);
        PageInfo<CourseExamPaperStudentListDTO> page = courseExamPaperStudentService.pageStudentList(dto, dto);
        return R.data(page);
    }

    /**
     * 获取学生试卷详情
     */
    @Operation(summary = "获取学生试卷详情")
    @GetMapping("/{exam-id}/student/{student-id}/detail")
    public R<CourseExamPaperStudentDetailDTO> findById(
        @Parameter(description = "测评ID", example = "100001") @PathVariable("exam-id") Long examId,
        @Parameter(description = "学生ID", example = "100001") @PathVariable("student-id") Long studentId
    ) {
        CourseExamPaperStudentDetailDTO dto = courseExamPaperStudentService.findPaperDetail(examId, studentId, true);
        return R.data(dto);
    }

    /**
     * 获取当前学生试卷
     */
    @Operation(summary = "获取当前学生试卷-学生端")
    @GetMapping("/{exam-id}/student/detail/current")
    public R<CourseExamPaperStudentDetailDTO> findById(
        @Parameter(description = "测评ID", example = "100001") @PathVariable("exam-id") Long examId
    ) {
        CourseExamPaperEntity examPaper = courseExamPaperStudentService.getExamPaper(examId);
        CourseExamPaperStudentDetailDTO dto = courseExamPaperStudentService.findCurrentPaperDetail(examId,
            studentHelp.getStudentId(examPaper.getClassId()));
        return R.data(dto);
    }

    /**
     * 修改课程测评学生答题
     */
    @Operation(summary = "修改课程测评学生答题")
    @PutMapping("/{exam-id}/student/{id}")
    public R<Boolean> update(
        @Parameter(description = "测评ID", example = "100001") @PathVariable("exam-id") Long examId,
        @Parameter(description = "id", example = "100001") @PathVariable("id") Long id,
        @RequestBody CourseExamPaperStudentUpdateDTO dto
    ) {
        dto.setId(id);
        return R.data(courseExamPaperStudentService.updateById(dto));
    }

    /**
     * 开始考试 - 学生
     */
    @Operation(summary = "开始考试 - 学生")
    @PutMapping("/student/start-paper")
    public R<CourseExamPaperStudentDetailDTO> generateStudentPaper(
        @RequestBody CourseExamPaperStudentStartDTO dto
    ) {
        CourseExamPaperEntity examPaper = courseExamPaperStudentService.getExamPaper(dto.getExamPaperId());
        dto.setStudentId(studentHelp.getStudentId(examPaper.getClassId()));
        return R.data(courseExamPaperStudentService.startPaper(dto));
    }

    /**
     * 提交试卷 - 学生
     */
    @Operation(summary = "提交试卷 - 学生")
    @PutMapping("/student/submit-paper")
    public R<Boolean> generateStudentPaper(
        @RequestBody CourseExamPaperStudentSubmitDTO dto
    ) {
        CourseExamPaperEntity examPaper = courseExamPaperStudentService.getExamPaper(dto.getExamPaperId());
        dto.setStudentId(studentHelp.getStudentId(examPaper.getClassId()));
        return R.data(courseExamPaperStudentService.submitPaper(dto));
    }

    /**
     * 批阅试卷 - 老师
     */
    @Operation(summary = "批阅试卷 - 老师")
    @PutMapping("/student/mark-paper")
    public R<Boolean> markPaper(
        @RequestBody CourseExamPaperStudentMarkDTO dto
    ) {
        return R.data(courseExamPaperStudentService.markPaper(dto));
    }

    /**
     * 打回试卷 - 老师
     */
    @Operation(summary = "打回试卷 - 老师")
    @PutMapping("/student/reject-paper")
    public R<Boolean> rejectPaper(
        @RequestBody CourseExamPaperStudentRejectDTO dto
    ) {
        return R.data(courseExamPaperStudentService.rejectPaper(dto));
    }

    /**
     * 一键催缴 - 老师
     */
    @Operation(summary = "一键催缴 - 老师")
    @PutMapping("/student/remind-paper")
    public R<Boolean> remindPaper(
        @RequestBody CourseExamPaperStudentRemindDTO dto
    ) {
        return R.data(courseExamPaperStudentService.remindPaper(dto.getExamPaperId()));
    }

    /**
     * 强制收卷 - 老师
     */
    @Operation(summary = "强制收卷 - 老师")
    @PutMapping("/student/force-paper")
    public R<Boolean> forcePaper(
        @RequestBody CourseExamPaperStudentRemindDTO dto
    ) {
        return R.data(courseExamPaperStudentService.forcePaper(dto.getExamPaperId()));
    }

    /**
     * 学生切屏 - 老师
     */
    @Operation(summary = "学生切屏")
    @PutMapping("/{exam-id}/screen-switch")
    public R<Boolean> screenSwitch(
        @Parameter(description = "测评ID", example = "100001") @PathVariable("exam-id") Long examId
    ) {
        CourseExamPaperEntity examPaper = courseExamPaperStudentService.getExamPaper(examId);
        return R.data(courseExamPaperStudentService.screenSwitch(examId,
            studentHelp.getStudentId(examPaper.getClassId())));
    }

    /**
     * 抽取学生回答 - 老师
     */
    @Operation(summary = "抽取学生回答 - 老师")
    @GetMapping("/{exam-id}/student/extract-answer")
    public R<CourseExamPaperExtractResultDTO> extractStudent(
        @Parameter(description = "测评ID", example = "100001") @PathVariable("exam-id") Long examId,
        @Parameter(description = "试题ID", example = "100001") @RequestParam("questionId") Long questionId
    ) {
        return R.data(courseExamPaperStudentService.extractAnswer(examId, questionId));
    }

    /**
     * 查询用户列表
     */
    @Operation(summary = "查询用户列表")
    @GetMapping("/user/list")
    public R<List<UserBaseInfoDO>> userList(
        @Parameter(description = "用户Id列表", example = "100001") @RequestParam("userIds") Long[] userIds
    ) {
        if (ArrayUtils.isEmpty(userIds)) {
            throw CommonErrors.BAD_REQUEST.asException("用户Id列表不能为空");
        }
        List<Long> list = Stream.of(userIds).filter(v -> v != null && v > 0).collect(Collectors.toList());
        return R.data(commonClassManager.findUserInfoByUserIds(list));
    }

    /**
     * 查询用户列表
     */
    @Operation(summary = "查询用户列表")
    @PostMapping("/user/list")
    public R<List<UserBaseInfoDO>> userListPost(
        @RequestBody IdsDTO idsDTO
    ) {
        return R.data(commonClassManager.findUserInfoByUserIds(idsDTO.getIds()));
    }

    /**
     * 手动补录试卷 - 老师
     */
    @Operation(summary = "手动补录试卷 - 老师")
    @PostMapping("/student/manual-supplement")
    public R<Boolean> manualSupplement(
        @RequestBody CourseExamPaperStudentManualDTO dto
    ) {
        return R.data(courseExamPaperStudentService.manualSupplement(dto));
    }

}
